package com.boot.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.SignatureException;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;

import java.util.Date;


@Component
@ConfigurationProperties(prefix = "jwt")
@Setter
public class JwtUtil {
    private static SecretKey tokenSignKey;
    private  Integer tokenExpiration;
    private  Integer refreshTokenExpiration;

    static {
        try {
            tokenSignKey = CreateHS512Key.getSecretKey();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create SecretKey", e);
        }
    }

    public String createToken(Long userId) {
        Claims claims = Jwts.claims()
                .setSubject(String.valueOf(userId))
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration * 60000));
        return Jwts.builder()
                .setClaims(claims)
                .signWith(tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }

    public Long getUserId(String token) {
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(tokenSignKey)
                .build()
                .parseClaimsJws(token)
                .getBody();
        String userId = claims.getSubject();
        return Long.parseLong(userId);
    }

    public Boolean isTokenExpired(String token) {
        try {
            return Jwts.parserBuilder()
                    .setSigningKey(tokenSignKey)
                    .build().parseClaimsJws(token).getBody().getExpiration().before(new Date());
        } catch (Exception e) {
            return true;
        }
    }

    public String CrateRefreshToken(Long userId) {
        Claims claims = Jwts.claims().setSubject(String.valueOf(userId))
                .setExpiration(new Date(System.currentTimeMillis() + refreshTokenExpiration * 60000));
        return Jwts.builder()
                .setClaims(claims)
                .signWith(tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }

    public String refreshToken(String refreshToken) {
        Boolean tokenExpired = isTokenExpired(refreshToken);
        if (!tokenExpired) {
            return createToken(getUserId(refreshToken));
        } else {
            return null;
        }
    }
}
